#define NOMINMAX
#include <GL\glew.h>
/*#include "LightManager.h"
#include "OpenMeshHalfEdge.h"
#include "Camera.h"

OpenMeshHalfEdge::OpenMeshHalfEdge(void):SceneItem(QString("Unnamed Polygon Mesh"))
{
  meshData.request_vertex_normals();

  // Add face normals as default property
  meshData.request_face_normals();

}


OpenMeshHalfEdge::OpenMeshHalfEdge(QString &name):SceneItem(name)
{
  meshData.request_vertex_normals();

  // Add face normals as default property
  meshData.request_face_normals();

}

OpenMeshHalfEdge::~OpenMeshHalfEdge(void)
{
}

void OpenMeshHalfEdge::createCylinder(float x,float y,float z,float radius, float height, int seglongitude,int segradius,int segheight)
{



	segradius=10;
	seglongitude=20;
	segheight=10;

	if(seglongitude<3 || segheight <1 || segradius<1)
		return;

	const double PI = 3.14159265358979323846264338327950288419717;
	const double TWOPI = 2.0*PI;

	MyMesh::VertexHandle top=meshData.add_vertex(MyMesh::Point(0,0,height*0.5f));
	MyMesh::VertexHandle bottom=meshData.add_vertex(MyMesh::Point(0,0,-height*0.5f));

	MyMesh::VertexHandle *topFirstRadius=new MyMesh::VertexHandle[segradius];
	MyMesh::VertexHandle *topPreRadius=new MyMesh::VertexHandle[segradius];
	MyMesh::VertexHandle *bottomFirstRadius=new MyMesh::VertexHandle[segradius];
	MyMesh::VertexHandle *bottomPreRadius=new MyMesh::VertexHandle[segradius];

	float radiusStep=radius/(float)(segradius);

	for(int i=1;i<segradius+1;++i)
	{
		float px=radiusStep*i;
		float py=0;
		float pz=height*0.5f;

		topFirstRadius[i-1]=topPreRadius[i-1]=meshData.add_vertex(MyMesh::Point(px,py,pz));
		pz=-height*0.5f;
		bottomFirstRadius[i-1]=bottomPreRadius[i-1]=meshData.add_vertex(MyMesh::Point(px,py,pz));
	}

	float longRotationStep=TWOPI/(float)seglongitude;

	MyMesh::VertexHandle *topCurRadius=new MyMesh::VertexHandle[segradius];
	MyMesh::VertexHandle *bottomCurRadius=new MyMesh::VertexHandle[segradius];

	MyMesh::VertexHandle *heightFirst=new MyMesh::VertexHandle[segheight+1];
	MyMesh::VertexHandle *heightCur=new MyMesh::VertexHandle[segheight+1];
	MyMesh::VertexHandle *heightPre=new MyMesh::VertexHandle[segheight+1];

	float heightStep=height/(float)segheight;

	for(int e=1;e<segheight;++e)
	{
		heightFirst[e]=heightPre[e]=meshData.add_vertex(MyMesh::Point(radius,0,height*0.5f-e*heightStep));
	}

	heightFirst[0]=heightPre[0]=topPreRadius[segradius-1];
	heightFirst[segheight]=heightPre[segheight]=bottomPreRadius[segradius-1];

	for(int i=1;i<seglongitude;++i)
	{
		float cosan=cos(i*longRotationStep);
		float sinan=sin(i*longRotationStep);

		float px=0;
		float py=0;

		for(int e=1;e<segradius+1;++e)
		{
			px=cosan*radiusStep*e;
			py=sinan*radiusStep*e;
			float pz=height*0.5f;

			topCurRadius[e-1]=meshData.add_vertex(MyMesh::Point(px,py,pz));

			pz=-height*0.5f;

			bottomCurRadius[e-1]=meshData.add_vertex(MyMesh::Point(px,py,pz));

		}


		MyMesh::VertexHandle triangle[3];
		triangle[0]=topCurRadius[0];
		triangle[1]=top;
		triangle[2]=topPreRadius[0];

		meshData.add_face(triangle,3);

		triangle[0]=bottomPreRadius[0];
		triangle[1]=bottom;
		triangle[2]=bottomCurRadius[0];

		meshData.add_face(triangle,3);

		for(int e=1;e<segradius;++e)
		{
			MyMesh::VertexHandle face[4];

			face[0]=topCurRadius[e];
			face[1]=topCurRadius[e-1];
			face[2]=topPreRadius[e-1];
			face[3]=topPreRadius[e];

			meshData.add_face(face,4);

			face[0]=bottomPreRadius[e];
			face[1]=bottomPreRadius[e-1];
			face[2]=bottomCurRadius[e-1];
			face[3]=bottomCurRadius[e];
			
			meshData.add_face(face,4);
		}

		for(int e=1;e<segheight;++e)
		{
			heightCur[e]=meshData.add_vertex(MyMesh::Point(px,py,height*0.5f-e*heightStep));
		}

		heightCur[0]=topCurRadius[segradius-1];
		heightCur[segheight]=bottomCurRadius[segradius-1];

		for(int e=1;e<segheight+1;++e)
		{
			MyMesh::VertexHandle face[4];

			face[0]=heightCur[e];
			face[1]=heightCur[e-1];
			face[2]=heightPre[e-1];
			face[3]=heightPre[e];

			meshData.add_face(face,4);
		}

		for(int e=0;e<segradius;++e)
		{
			topPreRadius[e]=topCurRadius[e];
			bottomPreRadius[e]=bottomCurRadius[e];
		}

		for(int e=0;e<segheight+1;++e)
		{
			heightPre[e]=heightCur[e];
		}
	}

			
	MyMesh::VertexHandle triangle[3];
	triangle[0]=topFirstRadius[0];
	triangle[1]=top;
	triangle[2]=topPreRadius[0];
	meshData.add_face(triangle,3);
	
	triangle[0]=bottomPreRadius[0];
	triangle[1]=bottom;
	triangle[2]=bottomFirstRadius[0];
	meshData.add_face(triangle,3);

	for(int e=1;e<segradius;++e)
	{
		MyMesh::VertexHandle face[4];

		face[0]=topFirstRadius[e];
		face[1]=topFirstRadius[e-1];
		face[2]=topPreRadius[e-1];
		face[3]=topPreRadius[e];

		meshData.add_face(face,4);

		face[0]=bottomPreRadius[e];
		face[1]=bottomPreRadius[e-1];
		face[2]=bottomFirstRadius[e-1];
		face[3]=bottomFirstRadius[e];
			
		meshData.add_face(face,4);
	}

			
	for(int e=1;e<segheight+1;++e)
	{
		MyMesh::VertexHandle face[4];
		face[0]=heightFirst[e];
		face[1]=heightFirst[e-1];
		face[2]=heightPre[e-1];
		face[3]=heightPre[e];

		meshData.add_face(face,4);
	}


	delete [] heightFirst;

	delete [] heightCur;
	delete [] heightPre;

	delete [] topCurRadius;
	delete [] bottomCurRadius;
	delete [] topFirstRadius;
	delete [] topPreRadius;
	delete [] bottomFirstRadius;
	delete [] bottomPreRadius;

	if(meshData.has_face_normals() && meshData.has_vertex_normals())
	{
		meshData.update_normals();
	}

	updateBoundingBox();
}

void OpenMeshHalfEdge::createBall(enum CreateDirectionType type,float x,float y,float z,float r,int seglongitude,int seglatitude )
{
	//type=DIRECTIONY;

	if(seglongitude<3 || seglatitude<1)
		return;
	
	const double PI = 3.14159265358979323846264338327950288419717;
	const double TWOPI = 2.0*PI;

	MyMesh::VertexHandle top=meshData.add_vertex(MyMesh::Point(0,0,r));
	MyMesh::VertexHandle bottom=meshData.add_vertex(MyMesh::Point(0,0,-r));

	MyMesh::VertexHandle *firstLongitude=new MyMesh::VertexHandle[seglatitude*2+1];
	MyMesh::VertexHandle *preLongitude=new MyMesh::VertexHandle[seglatitude*2+1];
	MyMesh::VertexHandle *curLongitude=new MyMesh::VertexHandle[seglatitude*2+1];

	float longRotationStep=TWOPI/(float)seglongitude;
	float latiRotationStep=PI/(float)(seglatitude*2.0f);

	for(int i=1;i<seglatitude*2;++i)
	{
		float radius=r*sin(((float)i)*latiRotationStep);
		float height=r*cos(((float)i)*latiRotationStep);


		float px=radius*cos(0.0);
		float pz=height;
		float py=radius*sin(0.0);

		firstLongitude[i]=preLongitude[i]=meshData.add_vertex(MyMesh::Point(px,py,pz));
	}

	for(int e=1;e<seglongitude;++e)
	{
		for(int i=1;i<seglatitude*2;++i)
		{
					
			float radius=r*sin(((float)i)*latiRotationStep);
			float height=r*cos(((float)i)*latiRotationStep);
			float px=radius*cos((double)longRotationStep*e);
			float py=radius*sin((double)longRotationStep*e);
			float pz=height;

			curLongitude[i]=meshData.add_vertex(MyMesh::Point(px,py,pz));
		}

		MyMesh::VertexHandle triangle[3];

		triangle[0]=curLongitude[1];
		triangle[1]=top;
		triangle[2]=preLongitude[1];
		
		meshData.add_face(triangle,3);

		triangle[0]=curLongitude[seglatitude*2-1];
		triangle[1]=preLongitude[seglatitude*2-1];
		triangle[2]=bottom;

		meshData.add_face(triangle,3);


		for(int i=2;i<seglatitude*2;++i)
		{
			MyMesh::VertexHandle facet[4];

			facet[0]=curLongitude[i];
			facet[1]=curLongitude[i-1];
			facet[2]=preLongitude[i-1];
			facet[3]=preLongitude[i];

			meshData.add_face(facet,4);
		}


		for(int i=1;i<seglatitude*2;++i)
		{
			preLongitude[i]=curLongitude[i];
		}
	}

	MyMesh::VertexHandle triangle[3];
	triangle[0]=firstLongitude[1];
	triangle[1]=top;
	triangle[2]=preLongitude[1];
	
	meshData.add_face(triangle,3);
	triangle[0]=firstLongitude[seglatitude*2-1];
	triangle[1]=preLongitude[seglatitude*2-1];
	triangle[2]=bottom;	
	meshData.add_face(triangle,3);

	for(int i=2;i<seglatitude*2;++i)	
	{
		MyMesh::VertexHandle facet[4];
		facet[0]=firstLongitude[i];
		facet[1]=firstLongitude[i-1];
		facet[2]=preLongitude[i-1];
		facet[3]=preLongitude[i];
		meshData.add_face(facet,4);
	}

	delete [] firstLongitude;
	delete [] preLongitude;
	delete [] curLongitude;

	switch(type)
	{
	case DIRECTIONX:
		{
			MyMesh::VertexIter vIter,vEnd(meshData.vertices_end());
			for(vIter=meshData.vertices_begin();vIter!=vEnd;++vIter)
			{
				GGL::Point3f &position=meshData.point(vIter);
				float temp=position.Z();
				position.Z()=-position.X();
				position.X()=temp;

				position.X()+=x;
				position.Y()+=y;
				position.Z()+=z;
			}
		}		
		break;
		case DIRECTIONY:
			{
				MyMesh::VertexIter vIter,vEnd(meshData.vertices_end());
				for(vIter=meshData.vertices_begin();vIter!=vEnd;++vIter)
				{
					GGL::Point3f &position=meshData.point(vIter);
					float temp=position.Z();
					position.Z()=-position.Y();
					position.Y()=temp;
								
					position.X()+=x;
					position.Y()+=y;
					position.Z()+=z;
				}
			}		
			break;
		case DIRECTIONZ:			
			{
				MyMesh::VertexIter vIter,vEnd(meshData.vertices_end());
				for(vIter=meshData.vertices_begin();vIter!=vEnd;++vIter)
				{		
					GGL::Point3f &position=meshData.point(vIter);
					position.X()+=x;
					position.Y()+=y;
					position.Z()+=z;
				}
			}		
			break;
		default:
			break;
	}

	if(meshData.has_face_normals() && meshData.has_vertex_normals())
	{
		meshData.update_normals();
	}

	updateBoundingBox();
}

void OpenMeshHalfEdge::drawForSelection(int mode,int type,unsigned int ID)
{
	switch(mode)
	{
	case Points:	
		{		
			glUseProgram(0);
			glEnable(GL_POLYGON_OFFSET_FILL);
			glDisable(GL_LIGHTING);
			glPolygonOffset(1, 1);
			glColorMask(0,0,0,0);

			MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
			for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
			{
				GGL::Point3f normal=meshData.normal(fIter);
				glBegin(GL_POLYGON);
				glNormal3f(normal.X(),normal.Y(),normal.Z());
				for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
				{
					GGL::Point3f aPoint=meshData.point(fvIter);
					glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
				}
				glEnd();
			}

			glColorMask(1,1,1,1);
			glColor3ub(62,142,183);
			glPointSize(3);
			glBegin(GL_POINTS);

			MyMesh::VertexIter vIter,vEnd(meshData.vertices_end());
			for(vIter=meshData.vertices_begin();vIter!=vEnd;++vIter)
			{
				GGL::Point3f v=meshData.point(vIter);
	
				glVertex3f(v.X(),v.Y(),v.Z());
			}
			glEnd();
		}
		break;
	case Lines:
		{		
			glUseProgram(0);
			glEnable(GL_POLYGON_OFFSET_FILL);
			glDisable(GL_LIGHTING);
			glPolygonOffset(1, 1);
			glColorMask(0,0,0,0);

			MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
			for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
			{
				GGL::Point3f normal=meshData.normal(fIter);
				glBegin(GL_POLYGON);
				glNormal3f(normal.X(),normal.Y(),normal.Z());
				for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
				{
					GGL::Point3f aPoint=meshData.point(fvIter);
					glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
				}
				glEnd();
			}

			glColorMask(1,1,1,1);
			glColor3ub(62,142,183);
	
			glBegin(GL_LINES);
			MyMesh::EdgeIter eIter,eEnd(meshData.edges_end());
			for(eIter=meshData.edges_begin();eIter!=eEnd;++eIter)
			{
				GGL::Point3f p1=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter, 1)));		
				GGL::Point3f p2=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter,0)));

				glVertex3f(p1.X(),p1.Y(),p1.Z());
				glVertex3f(p2.X(),p2.Y(),p2.Z());
			}
			glEnd();
		}
		break;
	case Facets:
		{		
			glUseProgram(0);
			glDisable(GL_LIGHTING);
			glColor3ub(62,142,183);
			MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
			for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
			{
				GGL::Point3f normal=meshData.normal(fIter);
				glBegin(GL_POLYGON);
				glNormal3f(normal.X(),normal.Y(),normal.Z());
				for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
				{
					GGL::Point3f aPoint=meshData.point(fvIter);
					glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
				}
				glEnd();
			}
		}
		break;
	case Object:
		{

			switch(type)
			{
			case Stencil:
				{
					glUseProgram(0);
					glDisable(GL_LIGHTING);
					glColor3ub(0,0,0);
					MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
					for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
					{
						glBegin(GL_POLYGON);
						for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
						{
							GGL::Point3f aPoint=meshData.point(fvIter);
							glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
						}
						glEnd();
					}
				}
				break;

			case ColorCode:
				{
					struct TempColor color=uint2Color(ID);
					glUseProgram(0);
					glDisable(GL_LIGHTING);
					glColor3ub(color.r,color.g,color.b);
					MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
					for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
					{
						
						glBegin(GL_POLYGON);
			
						for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
						{
							GGL::Point3f aPoint=meshData.point(fvIter);
							glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
						}
						glEnd();
					}
				}
				break;
			}
		}
		break;
	}
}

void OpenMeshHalfEdge::draw(int mode,Camera *currentCamera)
{	
	//shadingMode=mode;
	setShowWireFrame(true);
	switch(mode)
	{
		case SceneItem::Facet:
		{
			if(isShowWireFrame() || isSelected())
			{
				glEnable(GL_POLYGON_OFFSET_FILL);
				glPolygonOffset(1, 1);
			}
			Light *cameraLight=currentCamera->getCameraLight();
			LightManager::getSingleton().beginLighting();
			while(LightManager::getSingleton().setLights(cameraLight))
			{
				MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
				for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
				{
					GGL::Point3f normal=meshData.normal(fIter);
					glBegin(GL_POLYGON);
					glNormal3f(normal.X(),normal.Y(),normal.Z());
					for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
					{
						GGL::Point3f aPoint=meshData.point(fvIter);
						glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
					}
					glEnd();
				}
			}

			LightManager::getSingleton().endLighting();

			if(isSelected())
			{
				glDisable(GL_POLYGON_OFFSET_FILL);
				glDisable(GL_LIGHTING);
				glUseProgram(0);
				//printf("[%d]\n",meshData.n_edges() );
				glColor3ub(209,252,105);
				glBegin(GL_LINES);
				MyMesh::EdgeIter eIter,eEnd(meshData.edges_end());

				for(eIter=meshData.edges_begin();eIter!=eEnd;++eIter)
				{
					GGL::Point3f p1=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter, 1)));
					GGL::Point3f p2=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter,0)));
	
					glVertex3f(p1.X(),p1.Y(),p1.Z());
					glVertex3f(p2.X(),p2.Y(),p2.Z());
				}	
				glEnd();
			}
			else if(isShowWireFrame())
			{
				glDisable(GL_POLYGON_OFFSET_FILL);
				glDisable(GL_LIGHTING);
				glUseProgram(0);
				//printf("[%d]\n",meshData.n_edges() );
				glColor3ub(62,142,183);
				glBegin(GL_LINES);
				MyMesh::EdgeIter eIter,eEnd(meshData.edges_end());

				for(eIter=meshData.edges_begin();eIter!=eEnd;++eIter)
				{
					GGL::Point3f p1=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter, 1)));
					GGL::Point3f p2=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter,0)));
	
					glVertex3f(p1.X(),p1.Y(),p1.Z());
					glVertex3f(p2.X(),p2.Y(),p2.Z());
				}	
				glEnd();
			}
		}
		break;

	case SceneItem::Smooth:	
		{
			if(isShowWireFrame())
			{
				glEnable(GL_POLYGON_OFFSET_FILL);
				glPolygonOffset(1, 1);
			}
			Light *cameraLight=currentCamera->getCameraLight();
			LightManager::getSingleton().beginLighting();
			while(LightManager::getSingleton().setLights(cameraLight))
			{
				MyMesh::FaceIter fIter,fEnd(meshData.faces_end());
				for(fIter=meshData.faces_begin();fIter!=fEnd;++fIter)
				{
					glBegin(GL_POLYGON);
					for(MyMesh::FaceVertexIter fvIter=meshData.fv_iter(fIter);fvIter;++fvIter)
					{
						GGL::Point3f normal=meshData.normal(fvIter);
						glNormal3f(normal.X(),normal.Y(),normal.Z());
						GGL::Point3f aPoint=meshData.point(fvIter);
						glVertex3f(aPoint.X(),aPoint.Y(),aPoint.Z());
					}
					glEnd();
				}
			}

			LightManager::getSingleton().endLighting();

			if(isShowWireFrame())
			{
				glDisable(GL_POLYGON_OFFSET_FILL);
				glDisable(GL_LIGHTING);
				glUseProgram(0);
				//printf("[%d]\n",meshData.n_edges() );
				glColor3ub(62,142,183);
				glBegin(GL_LINES);
				MyMesh::EdgeIter eIter,eEnd(meshData.edges_end());

				for(eIter=meshData.edges_begin();eIter!=eEnd;++eIter)
				{
					GGL::Point3f p1=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter, 1)));
					GGL::Point3f p2=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter,0)));
	
					glVertex3f(p1.X(),p1.Y(),p1.Z());
					glVertex3f(p2.X(),p2.Y(),p2.Z());
				}	
				glEnd();
			}
		}
		break;
	case SceneItem::WireFrame:
		{
			glDisable(GL_LIGHTING);
			glUseProgram(0);

			glColor3ub(62,142,183);
			glBegin(GL_LINES);

			MyMesh::EdgeIter eIter,eEnd(meshData.edges_end());
			for(eIter=meshData.edges_begin();eIter!=eEnd;++eIter)
			{
				GGL::Point3f p1=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter, 1)));
				GGL::Point3f p2=meshData.point(meshData.to_vertex_handle(meshData.halfedge_handle(eIter,0)));
	
				glVertex3f(p1.X(),p1.Y(),p1.Z());
				glVertex3f(p2.X(),p2.Y(),p2.Z());
			}	
			glEnd();
	
		}
		break;
	}
}

void OpenMeshHalfEdge::updateBoundingBox()
{
	m_boundingBox.SetNull();
	MyMesh::VertexIter vIter,vEnd(meshData.vertices_end());
	for(vIter=meshData.vertices_begin();vIter!=vEnd;++vIter)
	{
		GGL::Point3f p=meshData.point(vIter);

		m_boundingBox.Add(p);
	}
}

void OpenMeshHalfEdge::createBox(float x,float y,float z,float lengthX,float lengthY,float lengthZ,int segx,int segy,int segz)
{
	if(segx<1 || segy<1 || segz<1)
		return;

	MyMesh::VertexHandle eightPoint[8];

	eightPoint[0]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y-lengthY*0.5f,z-lengthZ*0.5f));
	eightPoint[1]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y+lengthY*0.5f,z-lengthZ*0.5f));
	eightPoint[2]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y+lengthY*0.5f,z-lengthZ*0.5f));
	eightPoint[3]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y-lengthY*0.5f,z-lengthZ*0.5f));

	eightPoint[4]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y-lengthY*0.5f,z+lengthZ*0.5f));
	eightPoint[5]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y+lengthY*0.5f,z+lengthZ*0.5f));
	eightPoint[6]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y+lengthY*0.5f,z+lengthZ*0.5f));
	eightPoint[7]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y-lengthY*0.5f,z+lengthZ*0.5f));

	int xedgecount=segx+1;
	int yedgecount=segy+1;
	int zedgecount=segz+1;

	MyMesh::VertexHandle *edge1=new MyMesh::VertexHandle[xedgecount];
	MyMesh::VertexHandle *edge2=new MyMesh::VertexHandle[xedgecount];
	MyMesh::VertexHandle *edge3=new MyMesh::VertexHandle[xedgecount];
	MyMesh::VertexHandle *edge4=new MyMesh::VertexHandle[xedgecount];

	MyMesh::VertexHandle *edge5=new MyMesh::VertexHandle[yedgecount];
	MyMesh::VertexHandle *edge6=new MyMesh::VertexHandle[yedgecount];
	MyMesh::VertexHandle *edge7=new MyMesh::VertexHandle[yedgecount];
	MyMesh::VertexHandle *edge8=new MyMesh::VertexHandle[yedgecount];

	MyMesh::VertexHandle *edge9=new MyMesh::VertexHandle[zedgecount];
	MyMesh::VertexHandle *edge10=new MyMesh::VertexHandle[zedgecount];
	MyMesh::VertexHandle *edge11=new MyMesh::VertexHandle[zedgecount];
	MyMesh::VertexHandle *edge12=new MyMesh::VertexHandle[zedgecount];


	for(int i=1;i<xedgecount-1;++i)
	{
		edge1[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)i)*lengthX/(float)segx,y-lengthY*0.5f,z-lengthZ*0.5f));
		edge2[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)i)*lengthX/(float)segx,y+lengthY*0.5f,z-lengthZ*0.5f));
		edge3[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)i)*lengthX/(float)segx,y-lengthY*0.5f,z+lengthZ*0.5f));
		edge4[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)i)*lengthX/(float)segx,y+lengthY*0.5f,z+lengthZ*0.5f));
	}

	edge1[0]=eightPoint[3];
	edge1[xedgecount-1]=eightPoint[0];
	edge2[0]=eightPoint[2];
	edge2[xedgecount-1]=eightPoint[1];

	edge3[0]=eightPoint[7];
	edge3[xedgecount-1]=eightPoint[4];

	edge4[0]=eightPoint[6];
	edge4[xedgecount-1]=eightPoint[5];

	for(int i=1;i<yedgecount-1;++i)
	{
		edge5[i]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y-lengthY*0.5f+((float)i)*lengthY/(float)segy,z-lengthZ*0.5f));
		edge6[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y-lengthY*0.5f+((float)i)*lengthY/(float)segy,z-lengthZ*0.5f));
		edge7[i]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y-lengthY*0.5f+((float)i)*lengthY/(float)segy,z+lengthZ*0.5f));
		edge8[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y-lengthY*0.5f+((float)i)*lengthY/(float)segy,z+lengthZ*0.5f));
	}

	edge5[0]=eightPoint[0];
	edge5[yedgecount-1]=eightPoint[1];

	edge6[0]=eightPoint[3];
	edge6[yedgecount-1]=eightPoint[2];

	edge7[0]=eightPoint[4];
	edge7[yedgecount-1]=eightPoint[5];

	edge8[0]=eightPoint[7];
	edge8[yedgecount-1]=eightPoint[6];

	for(int i=1;i<zedgecount-1;++i)
	{
		edge9[i]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y-lengthY*0.5f,z-lengthZ*0.5f+((float)i)*lengthZ/(float)segz));
		edge10[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y-lengthY*0.5f,z-lengthZ*0.5f+((float)i)*lengthZ/(float)segz));
		edge11[i]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y+lengthY*0.5f,z-lengthZ*0.5f+((float)i)*lengthZ/(float)segz));
		edge12[i]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f,y+lengthY*0.5f,z-lengthZ*0.5f+((float)i)*lengthZ/(float)segz));
	}

	edge9[0]=eightPoint[0];
	edge9[zedgecount-1]=eightPoint[4];

	edge10[0]=eightPoint[3];
	edge10[zedgecount-1]=eightPoint[7];

	edge11[0]=eightPoint[2];
	edge11[zedgecount-1]=eightPoint[6];

	edge12[0]=eightPoint[1];
	edge12[zedgecount-1]=eightPoint[5];


	MyMesh::VertexHandle *bottom=new MyMesh::VertexHandle[xedgecount*yedgecount];
	MyMesh::VertexHandle *top=new MyMesh::VertexHandle[xedgecount*yedgecount];

	for(int i=0;i<xedgecount;++i)
	{
		bottom[i]=edge1[i];
		bottom[i+(yedgecount-1)*xedgecount]=edge2[i];
		
		top[i]=edge4[i];
		top[i+(yedgecount-1)*xedgecount]=edge3[i];
	}

	for(int i=0;i<yedgecount;++i)
	{
		bottom[i*xedgecount]=edge6[i];
		bottom[i*xedgecount+xedgecount-1]=edge5[i];

		top[i*xedgecount]=edge8[yedgecount-1-i];
		top[i*xedgecount+xedgecount-1]=edge7[yedgecount-1-i];
	}

	for(int xx=1;xx<xedgecount-1;++xx)
	{
		for(int yy=1;yy<yedgecount-1;++yy)
		{
			bottom[xx+yy*xedgecount]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)xx)*lengthX/(float)segx,y-0.5f*lengthY+((float)yy)*lengthY/(float)segy,z-lengthZ*0.5f));
			top[xx+yy*xedgecount]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)xx)*lengthX/(float)segx,y+0.5f*lengthY-((float)yy)*lengthY/(float)segy,z+lengthZ*0.5f));
		}
	}

	for(int xx=1;xx<xedgecount;++xx){
		for(int yy=1;yy<yedgecount;++yy)
		{
			MyMesh::VertexHandle face_vhandles[4];
			
			face_vhandles[0]=bottom[xx+yy*xedgecount];
			face_vhandles[1]=bottom[xx+(yy-1)*xedgecount];
			face_vhandles[2]=bottom[xx-1+(yy-1)*xedgecount];
			face_vhandles[3]=bottom[xx-1+yy*xedgecount];

			meshData.add_face(face_vhandles,4);

			face_vhandles[0]=top[xx+yy*xedgecount];
			face_vhandles[1]=top[xx+(yy-1)*xedgecount];
			face_vhandles[2]=top[xx-1+(yy-1)*xedgecount];
			face_vhandles[3]=top[xx-1+yy*xedgecount];

			meshData.add_face(face_vhandles,4);

		}
	}

	MyMesh::VertexHandle *front=new MyMesh::VertexHandle[xedgecount*zedgecount];
	MyMesh::VertexHandle *back=new MyMesh::VertexHandle[xedgecount*zedgecount];

	for(int i=0;i<xedgecount;++i)
	{
		front[i]=edge3[i];
		front[i+xedgecount*(zedgecount-1)]=edge1[i];

		back[i]=edge4[(xedgecount-1)-i];
		back[i+xedgecount*(zedgecount-1)]=edge2[(xedgecount-1)-i];
	}

	for(int i=0;i<zedgecount;++i)
	{
		front[i*xedgecount]=edge10[(zedgecount-1)-i];
		front[i*xedgecount+xedgecount-1]=edge9[(zedgecount-1)-i];

		back[i*xedgecount]=edge12[(zedgecount-1)-i];
		back[i*xedgecount+xedgecount-1]=edge11[(zedgecount-1)-i];
	}

	for(int xx=1;xx<xedgecount-1;++xx)
	{
		for(int zz=1;zz<zedgecount-1;++zz)
		{
			front[xx+zz*xedgecount]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f+((float)xx)*lengthX/(float)segx,y-lengthY*0.5f,z+lengthZ*0.5f-((float)zz)*lengthZ/(float)segz));
			back[xx+zz*xedgecount]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5f-((float)xx)*lengthX/(float)segx,y+lengthY*0.5f,z+lengthZ*0.5f-((float)zz)*lengthZ/(float)segz));
		}
	}

	for(int xx=1;xx<xedgecount;++xx){
		for(int zz=1;zz<zedgecount;++zz)
		{
			MyMesh::VertexHandle face_vhandles[4];
			
			face_vhandles[0]=front[xx+zz*xedgecount];
			face_vhandles[1]=front[xx+(zz-1)*xedgecount];
			face_vhandles[2]=front[xx-1+(zz-1)*xedgecount];
			face_vhandles[3]=front[xx-1+zz*xedgecount];

			meshData.add_face(face_vhandles,4);

			face_vhandles[0]=back[xx+zz*xedgecount];
			face_vhandles[1]=back[xx+(zz-1)*xedgecount];
			face_vhandles[2]=back[xx-1+(zz-1)*xedgecount];
			face_vhandles[3]=back[xx-1+zz*xedgecount];

			meshData.add_face(face_vhandles,4);

		}
	}

	MyMesh::VertexHandle *left=new MyMesh::VertexHandle[yedgecount*zedgecount];
	MyMesh::VertexHandle *right=new MyMesh::VertexHandle[yedgecount*zedgecount];

	for(int i=0;i<yedgecount;++i)
	{
		left[i]=edge8[(yedgecount-1)-i];
		left[i+yedgecount*(zedgecount-1)]=edge6[(yedgecount-1)-i];

		right[i]=edge7[i];
		right[i+yedgecount*(zedgecount-1)]=edge5[i];
	}

	for(int i=0;i<zedgecount;++i)
	{
		left[i*yedgecount]=edge11[(zedgecount-1)-i];
		left[i*yedgecount+yedgecount-1]=edge10[(zedgecount-1)-i];

		right[i*yedgecount]=edge9[(zedgecount-1)-i];
		right[i*yedgecount+yedgecount-1]=edge12[(zedgecount-1)-i];
	}

	for(int yy=1;yy<yedgecount-1;++yy)
	{
		for(int zz=1;zz<zedgecount-1;++zz)
		{
			left[yy+zz*yedgecount]=meshData.add_vertex(MyMesh::Point(x-lengthX*0.5f,y+lengthY*0.5-((float)yy)*lengthY/(float)segy,z+lengthZ*0.5f-((float)zz)*lengthZ/(float)segz));
			right[yy+zz*yedgecount]=meshData.add_vertex(MyMesh::Point(x+lengthX*0.5,y-lengthY*0.5+((float)yy)*lengthY/(float)segy,z+lengthZ*0.5f-((float)zz)*lengthZ/(float)segz));
		}
	}


	for(int yy=1;yy<yedgecount;++yy){
		for(int zz=1;zz<zedgecount;++zz)
		{
			MyMesh::VertexHandle face_vhandles[4];
			
			face_vhandles[0]=left[yy+zz*yedgecount];
			face_vhandles[1]=left[yy+(zz-1)*yedgecount];
			face_vhandles[2]=left[yy-1+(zz-1)*yedgecount];
			face_vhandles[3]=left[yy-1+zz*yedgecount];

			meshData.add_face(face_vhandles,4);

			face_vhandles[0]=right[yy+zz*yedgecount];
			face_vhandles[1]=right[yy+(zz-1)*yedgecount];
			face_vhandles[2]=right[yy-1+(zz-1)*yedgecount];
			face_vhandles[3]=right[yy-1+zz*yedgecount];

			meshData.add_face(face_vhandles,4);

		}
	}

	delete [] left;
	delete [] right;

	delete [] front;
	delete [] back;
		
	delete [] top;
	delete [] bottom;

	delete [] edge12;
	delete [] edge11;
	delete [] edge10;
	delete [] edge9;

	delete [] edge8;
	delete [] edge7;
	delete [] edge6;
	delete [] edge5;


	delete [] edge4;
	delete [] edge3;
	delete [] edge2;
	delete [] edge1;





	if(meshData.has_face_normals() && meshData.has_vertex_normals())
	{
		meshData.update_normals();
	}

	updateBoundingBox();
}
*/